package port;
import java.io.IOException;
import java.net.*;

public class UdpPort {
	//当前客户端
	private UdpClient current;
	//端口号
	private int id;
	//端口UDP套接字
	private DatagramSocket socket=null;
	//输入报文包
	private DatagramPacket inPacket;
	//输出报文包
	private DatagramPacket outPacket;
	//输入数据缓存
	private Buffer inBuf;
	
	
	
	/*方法：构造函数
	 *功能：1 指定端口创建UDP套接字；2 保存端口号；3创建输入报文包;4 返回操作状态
	 *描述：通过构造函数，使得在创建该类对象的同时，创建好该端口的套接字和输入报文包。
	 *参数：portId->指定的端口号 
	 *版本：v2 ,2014-5-19
	 *作者：YuePing  , tellHow 
	 * */
	public boolean UdpPort(int portId) 
	{
	  try
	  {
		 //创建UDP套接字
	    this.socket=new DatagramSocket(portId);			
	    //保存端口号
	    this.id=portId;											
	    //创建输入报文包
	    this.inPacket=new DatagramPacket(inBuf.buf,inBuf.lenght);
	    //返回操作成功
		return true;
	  }
	  catch(SocketException e )
	  {
		//出现异常，返回操作失败
		return false;
	  }		  
	}
	
 /*方法：读数据
  *功能：1 接收UDP报文；2获取客户端网络地址 ；3 获取客户端端口；4 写出输入数据 ；5返回操作状态
  *描述：该方法将广播接收从指定的端口输入的报文包，输入的报文中包含数据、客户端地址和端口等信息
  *参数：buffer->读入的数据；
  *	版本：v2 ,2014-5-19
  *作者：YuePing  , tellHow  
  * */
  public boolean Read(Buffer buffer)	
  {
	  try
	  {
		  //接收报文包，存入inPacket，此处会产生一个阻塞
		  socket.receive(inPacket);
		  //获取客户端的网络地址，存入当前客户端的网络地址current.netAddress
		  current.netAddress=inPacket.getAddress();
		  //获取客户端的端口，存入当前客户端的端口current.port
		  current.port=inPacket.getPort();
		  //把输入缓存区的数据写出到外部buf
		  buffer=this.inBuf;
		  //返回成功
		  return true;
	  }
	  catch(IOException e)
	  {
		  //出现异常，返回错误
		  return false;
	  }	  
  }
  /*方法：写数据
   *功能：1 生成输出报文包；2 端口写数据 ；3返回操作状态
   *描述：该方法将向当前的客户端发送数据
   *参数：buffer->要写的数据；client：客户端信息
   *版本：v2 ,2014-5-19
   *作者：YuePing  , tellHow  
   * */
  public boolean Write(Buffer buffer)
  {
	  try
	  {
		//生成一个输出报文包，包包含要写的数据、目标客户的网络地址和端口
		outPacket =new DatagramPacket(buffer.buf,buffer.lenght,current.netAddress,current.port);  
		//端口发送报文包
		socket.send(outPacket);
		//返回操作成功
		return true;
	  }
	  catch(IOException e)
	  {
		//出现异常，返回失败
	  return false;
	  }
  }
 
  /*方法：设置当前操作的客户
   *描述：在写数据之前，一定要先设置目标客户
   *版本：v2 ,2014-5-19
   *作者：YuePing  , tellHow  
   * */
  public void setClient(UdpClient client)
  {
	  this.current=client;
  }
  
  /*方法：获取当前客户
   * 描述：当读完输入报文后，使用该方法可以返回客户端的相关信息，如地址和端口
   *版本：v2 ,2014-5-19
   *作者：YuePing  , tellHow  
   */
  public UdpClient getClient()
  {
	  return current;
  }
  
}
